/**
 * @pluginDesc Enter키 입력시에 현재 줄을 P 태그로 감거나 <br> 태그를 삽입한다.
 */
nhn.husky.SE_WYSIWYGEnterKey = jindo.$Class({
	name : "SE_WYSIWYGEnterKey",

	$init : function(sLineBreaker){
		if(sLineBreaker == "BR"){
			this.sLineBreaker = "BR";
		}else{
			this.sLineBreaker = "P";
		}
		
		this.htBrowser = jindo.$Agent().navigator();
		
		// [SMARTEDITORSUS-227] IE 인 경우에도 에디터 Enter 처리 로직을 사용하도록 수정
		if(this.htBrowser.opera && this.sLineBreaker == "P"){
			this.$ON_MSG_APP_READY = function(){};
		}
	},
	
	$ON_MSG_APP_READY : function(){
		this.oSelection = this.oApp.getEmptySelection();
		jindo.$Fn(this._onKeyDown, this).attach(this.oApp.getWYSIWYGDocument(), "keydown");
	},
	
	_onKeyDown : function(oEvent){
		var oKeyInfo = oEvent.key();
		
		if(oKeyInfo.shift){
			return;
		}
		
		if(oKeyInfo.enter){
			if(this.sLineBreaker == "BR"){
				this._insertBR(oEvent);
			}else{
				this._wrapBlock(oEvent);
			}
		}
	},
	
	_wrapBlock : function(oEvent, sWrapperTagName){
		var oSelection = this.oApp.getSelection();
		var sBM = oSelection.placeStringBookmark();
		var oLineInfo = oSelection.getLineInfo();
		var oStart = oLineInfo.oStart;
		var oEnd = oLineInfo.oEnd;

		// line broke by sibling
		// or
		// the parent line breaker is just a block container
		if(!oStart.bParentBreak || oSelection.rxBlockContainer.test(oStart.oLineBreaker.tagName)){
			oEvent.stop();

			var oSWrapper = this.oApp.getWYSIWYGDocument().createElement(this.sLineBreaker);
			//oSelection.moveToStringBookmark(sBM, true);
			oSelection.moveToBookmark(sBM);
			oSelection.setStartBefore(oStart.oNode);
			oSelection.surroundContents(oSWrapper);
			oSelection.collapseToEnd();

			var oEWrapper = this.oApp.getWYSIWYGDocument().createElement(this.sLineBreaker);
			oSelection.setEndAfter(oEnd.oNode);
			oSelection.surroundContents(oEWrapper);

			oSelection.removeStringBookmark(sBM);

			var elStyleOnlyNode = oSWrapper;
			// insert a cursor holder(br) if there's an empty-styling-only-tag surrounding current cursor
			if(oSWrapper.innerHTML == "" || (elStyleOnlyNode = this._getStyleOnlyNode(oSWrapper))){
				elStyleOnlyNode.innerHTML = "<br>";
			}
			
			if(oEWrapper.lastChild !== null && oEWrapper.lastChild.tagName == "BR"){
				oEWrapper.removeChild(oEWrapper.lastChild);
			}
			elStyleOnlyNode = oEWrapper;
			if(oEWrapper.innerHTML == "" || (elStyleOnlyNode = this._getStyleOnlyNode(oEWrapper))){
				if(this.htBrowser.ie){	// [SMARTEDITORSUS-230] <br> 태그 부분에서 비정상적인 P 태그가 생성되어 오류 발생
					elStyleOnlyNode.innerHTML = unescape("%uFEFF");
				}else{
					elStyleOnlyNode.innerHTML = "<br>";
				}
			}

			if(oEWrapper.nextSibling && oEWrapper.nextSibling.tagName == "BR"){
				oEWrapper.parentNode.removeChild(oEWrapper.nextSibling);
			}

			oSelection.selectNodeContents(elStyleOnlyNode);
			oSelection.collapseToStart();
			
//			var elTmpCursor = this.oSelection._document.createTextNode(" ");
//			oSelection.insertNode(elTmpCursor);

//			oSelection.removeStringBookmark(sBM);

			//this.oApp.exec("REFRESH_WYSIWYG");
			oSelection.select();

			//elTmpCursor.nodeValue = "";

			this.oApp.exec("CHECK_STYLE_CHANGE", []);
		}else{
			if(this.htBrowser.firefox){
				var elBookmark = oSelection.getStringBookmark(sBM, true);
				if(elBookmark && elBookmark.nextSibling && elBookmark.nextSibling.tagName == "IFRAME"){
					setTimeout(jindo.$Fn(function(){
						var elBookmark = oSelection.getStringBookmark(sBM);
						if(!elBookmark){return;}

						oSelection.moveToStringBookmark(sBM);
						oSelection.select();
						oSelection.removeStringBookmark(sBM);
					}, this).bind(), 0);
				}else{
					oSelection.removeStringBookmark(sBM);
				}
			}else if(this.htBrowser.ie){	// [SMARTEDITORSUS-26] Enter 후에 밑줄/취소선이 복사되지 않는 문제를 처리
				var elBookmark = oSelection.getStringBookmark(sBM, true),
					elParentNode = elBookmark.parentNode,
					bAddUnderline = false,
					bAddLineThrough = false;

				if(!elBookmark || elBookmark.nextSibling || !elParentNode){
					oSelection.removeStringBookmark(sBM);
					return;
				}
								
				oSelection.removeStringBookmark(sBM);
				
				if(elParentNode.tagName === "U" || (elParentNode.parentNode && elParentNode.parentNode.tagName === "U")){
					bAddUnderline = true;
				}
				if(elParentNode.tagName === "S" || elParentNode.tagName === "STRIKE" || 
					(elParentNode.parentNode && (elParentNode.parentNode.tagName === "S" || elParentNode.parentNode.tagName === "STRIKE"))){
					bAddLineThrough = true;
				}

				if(!bAddUnderline && !bAddLineThrough){
					return;
				}
				
				var wfnAddTextDecorationTag = jindo.$Fn(function(){
					var oTargetNode, oNewNode,
						oNewSelection = this.oApp.getSelection();
						
					if(!oNewSelection.collapsed){
						return;
					}
								
					oTargetNode = oNewSelection.startContainer;

					while(oTargetNode){
						if(oTargetNode.nodeType === 3){
							oTargetNode = nhn.DOMFix.parentNode(oTargetNode);
							break;
						}
						
						if(!oTargetNode.childNodes || oTargetNode.childNodes.length == 0){
							break;
						}
						
						oTargetNode = oTargetNode.firstChild;	
					}
										
					if(!oTargetNode){
						return;
					}
					
					if(bAddUnderline){
						oNewNode = oNewSelection._document.createElement("U");
						oTargetNode.appendChild(oNewNode);
						oTargetNode = oNewNode;
					}

					if(bAddLineThrough){
						oNewNode = oNewSelection._document.createElement("STRIKE");
						oTargetNode.appendChild(oNewNode);
					}
					
					oNewNode.innerHTML = unescape("%uFEFF");
					oNewSelection.selectNodeContents(oNewNode);	
					oNewSelection.collapseToStart();
					oNewSelection.select();	
				}, this).bind();
				
				setTimeout(wfnAddTextDecorationTag, 0);
			}else{
				oSelection.removeStringBookmark(sBM);
			}
		}
	},
	
	// returns inner-most styling only node if there's any.
	// -> returns span3 from <span1><span2><span3></span></span></span>
	_getStyleOnlyNode : function(elNode){
		if(!elNode){
			return null;
		}

		// the final styling node must allow appending children
		// -> this doesn't seem to work for FF
		if(!elNode.insertBefore){
			return null;
		}
		
		if(elNode.tagName == "IMG" || elNode.tagName == "BR" || elNode.tagName == "HR" || elNode.tagName == "IFRAME"){
			return null;
		}
	
		while(elNode.firstChild && this.oSelection._isBlankTextNode(elNode.firstChild)){
			elNode.removeChild(elNode.firstChild);
		}

		if(elNode.childNodes.length>1){
			return null;
		}

		if(!elNode.firstChild){
			return elNode;
		}
		
		// [SMARTEDITORSUS-227] TEXT_NODE 가 return 되는 문제를 수정함. IE 에서 TEXT_NODE 의 innrHTML 에 접근하면 오류 발생
		if(elNode.firstChild.nodeType === 3){
			return (elNode.firstChild.textContents === null || elNode.firstChild.textContents === "" ? elNode : null);
		}

		return this._getStyleOnlyNode(elNode.firstChild);
	},
	
	_insertBR : function(oEvent){
		oEvent.stop();

		var oSelection = this.oApp.getSelection();

		var elBR = this.oApp.getWYSIWYGDocument().createElement("BR");
		oSelection.insertNode(elBR);
		oSelection.selectNode(elBR);
		oSelection.collapseToEnd();
		
		if(!this.htBrowser.ie){
			var oLineInfo = oSelection.getLineInfo();
			var oStart = oLineInfo.oStart;
			var oEnd = oLineInfo.oEnd;

			// line break by Parent
			// <div> 1234<br></div>인경우, FF에서는 다음 라인으로 커서 이동이 안 일어남.
			//그래서  <div> 1234<br><br type='_moz'/></div> 이와 같이 생성해주어야 에디터 상에 2줄로 되어 보임.
			if(oEnd.bParentBreak){
				while(oEnd.oNode && oEnd.oNode.nodeType == 3 && oEnd.oNode.nodeValue == ""){
					oEnd.oNode = oEnd.oNode.previousSibling;
				}

				var nTmp = 1;
				if(oEnd.oNode == elBR || oEnd.oNode.nextSibling == elBR){
					nTmp = 0;
				}

				if(nTmp === 0){
					oSelection.pasteHTML("<br type='_moz'/>");
					oSelection.collapseToEnd();
				}
			}
		}

		// the text cursor won't move to the next line without this
		oSelection.insertNode(this.oApp.getWYSIWYGDocument().createTextNode(""));
		oSelection.select();
	}
});
//}
